/*
 * @Author: i@rysa.cn
 * @Date: 2022-05-14 16:36:00
 * @LastEditTime: 2022-05-14 16:40:52
 * @LastEditors: i@rysa.cn
 * @Description:
 * @FilePath: \go-utils\wechat\mp\access_token\access_token.go
 */

package accesstoken

import (
	"encoding/json"
	"errors"
	"fmt"

	"gitee.com/rysa/go-utils/request"
	"gitee.com/rysa/go-utils/wechat/mp/mpconfig"
	"gitee.com/rysa/go-utils/wechat/mp/params"
)

type accessToken struct {
	*mpconfig.MpConfig
}

const (
	accessTokenKey = "mp_access_token"
	akUrl          = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"
)

func NewAccessToken(cfg *mpconfig.MpConfig) *accessToken {
	return &accessToken{cfg}
}

func GetAccessToken(mp *mpconfig.MpConfig) (string, error) {
	return NewAccessToken(mp).GetAccessToken()
}

func (mp *accessToken) GetAccessToken() (string, error) {
	tokenKey := accessTokenKey
	if mp.TokenKey != "" {
		tokenKey = mp.TokenKey
	}
	if !mp.Cache.IsExist(tokenKey) {
		err := mp.GetAccessTokenFromTencent()
		if err != nil {
			return "", err
		}
	}
	token, err := mp.Cache.Get(tokenKey)
	return token, err
}

/**
 * @name: 强制从微信服务器获取刷新token
 * @description:
 * @param {*}
 * @return {*}
 */
func (mp *accessToken) GetAccessTokenFromTencent() error {
	mp.Mutx.Lock()
	defer mp.Mutx.Unlock()
	url := akUrl + fmt.Sprintf("&appid=%s&secret=%s", mp.Appid, mp.Appsecret)
	req := request.NewRequest()
	res, err := req.Get(url)
	if err != nil {
		return err
	}
	var data params.AccessToken
	err = json.Unmarshal(res.Body(), &data)
	if err != nil {
		return err
	}
	if data.Errcode != 0 {
		return errors.New(data.Errmsg)
	}
	tokenKey := accessTokenKey
	if mp.TokenKey != "" {
		tokenKey = mp.TokenKey
	}
	return mp.Cache.Set(tokenKey, data.AccessToken, data.ExpiresIn)
}
